This document gives insights on school location data available for Nairobi, Kenya.
We look at data from WorldBank and OpenStreetMap (via Overpass API). For OpenStreetMap a little processing is necessary due to its datamodel and possibility of dual representation of schools as POI and building footprint. In the following chunk we download the data from OSM and check for overlaps of footprints and POIs.
osm_schools |> nrow()
## [1] 1877
selected_cols <- grep("education|name|osm_id|amenity", names(osm_schools), ignore.case = TRUE)
osm_schools <- osm_schools |> select(all_of(selected_cols))
osm_schools <- osm_schools |> st_filter(nairobi_boundary)
schools_wb <- schools_wb |>
st_transform(4326) |>
st_filter(nairobi_boundary)
schools_wb |> names()
## [1] "OBJECTID" "CODE" "SCHOOL_NAM" "LEVEL" "Status"
## [6] "County" "DISTRICT" "ZONE" "SUB_COUNTY" "Ward"
## [11] "X_Coord" "Y_Coord" "Source" "geometry"
# How many schools overlap within different distances
wb50_osm <- osm_schools |> st_transform(32637) |>
st_filter(schools_wb |>
st_transform(32637) |>
st_buffer(50) |> st_union()) |> nrow()
wb100_osm <- osm_schools |> st_transform(32637) |>
st_filter(schools_wb |>
st_transform(32637) |>
st_buffer(100) |> st_union()) |> nrow()
wb500_osm <- osm_schools |> st_transform(32637) |>
st_filter(schools_wb |>
st_transform(32637) |>
st_buffer(500) |> st_union()) |> nrow()
wb1000_osm <- osm_schools |> st_transform(32637) |>
st_filter(schools_wb |>
st_transform(32637) |>
st_buffer(1000) |> st_union()) |> nrow()
osm50_wb <- schools_wb |> st_transform(32637) |>
st_filter(osm_schools |>
st_transform(32637) |>
st_buffer(50) |> st_union()) |> nrow()
osm100_wb <- schools_wb |> st_transform(32637) |>
st_filter(osm_schools |>
st_transform(32637) |>
st_buffer(100) |> st_union()) |> nrow()
osm500_wb <- schools_wb |> st_transform(32637) |>
st_filter(osm_schools |>
st_transform(32637) |>
st_buffer(500) |> st_union()) |> nrow()
osm1000_wb <- schools_wb |> st_transform(32637) |>
st_filter(osm_schools |>
st_transform(32637) |>
st_buffer(1000) |> st_union()) |> nrow()
Total amount of schools per dataset.
| Dataset | Total amount of schools | |
|---|---|---|
| OSM | 1759 | |
| Worldbank | 2142 |
Overlap by distance from Wordlbank
| Coverage of WB | 50m | % | 100m | % | 500m | % | 1000m | % |
|---|---|---|---|---|---|---|---|---|
| OSM | 349 | 19.84 | 809 | 45.99 | 1722 | 97.9 | 1748 | 99.37 |
Overlap by distance from OpenStreetMap
| Coverage of OSM | 50m | % | 100m | % | 500m | % | 1000m | % |
|---|---|---|---|---|---|---|---|---|
| WB | 260 | 14.78 | 526 | 29.9 | 1587 | 90.22 | 1903 | 108.19 |
tmap_mode("view")
m.1 <- tm_basemap("OpenStreetMap") +
tm_shape(osm_schools) +
tm_dots(
col="turquoise",
size = .1,
border.lwd = 0,
popup.vars = c("osm_id", "amenity", "name", "education:students")
)
m.2 <- tm_basemap("OpenStreetMap") +
tm_shape(schools_wb) +
tm_dots(
col="firebrick",
size = .1,
border.lwd = 0,
popup.vars = c("SCHOOL_NAM", "LEVEL", "Status", "Source")
)
tmap_arrange(m.1,m.2, sync = T)
Also added a difference and worldpop map.
colrmp <- viridisLite::cividis(7)
colrmp[1] <- "#FFFFFF"
tmap_mode("view")
m.1 <- tm_basemap("OpenStreetMap") +
tm_shape(hex_grid) +
tm_polygons(
title = "Schools in WB",
col="count_wb",
border.lwd = .1,
breaks=c(0,1, 10, 20, 30, 50, 100, 150),
palette=colrmp
)
m.2 <- tm_basemap("OpenStreetMap") +
tm_shape(hex_grid) +
tm_polygons(
title = "Schools in OSM",
col="count_osm",
border.lwd = .1,
breaks=c(0,1, 10, 20, 30, 50, 100, 150),
palette=colrmp
)
m.3 <- tm_basemap("OpenStreetMap") +
tm_shape(hex_grid) +
tm_polygons(
title = "WB - OSM counts",
col="count_diff_wb_osm",
breaks=c(-100,-50,-10,-1,0,1,10,50,100),
border.lwd = .1,
palette="RdBu"
)
m.4 <- tm_basemap("OpenStreetMap") +
tm_shape(hex_grid) +
tm_polygons(
title = "Population WorldPop",
col="wpop",
border.lwd = .1,
breaks=c(0, 1, 100, 1000, 10000, 50000, 150000),
palette=colrmp
)
tmap_arrange(m.1,m.2,m.3,m.4,ncol = 2, nrow = 2, sync = T)